<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>HLS视频播放器</title>
  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: 'Roboto', sans-serif;
      background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
      color: #fff;
      min-height: 100vh;
      padding: 20px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .container {
      max-width: 1200px;
      width: 100%;
      background-color: rgba(0, 0, 0, 0.7);
      border-radius: 15px;
      padding: 30px;
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
      margin-top: 20px;
    }

    header {
      text-align: center;
      margin-bottom: 30px;
      padding-bottom: 20px;
      border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    h1 {
      font-size: 2.8rem;
      margin-bottom: 10px;
      text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
      background: linear-gradient(to right, #ff8a00, #da1b60);
      -webkit-background-clip: text;
      background-clip: text;
      color: transparent;
    }

    .subtitle {
      font-size: 1.2rem;
      opacity: 0.9;
      margin-bottom: 20px;
    }

    .player-container {
      position: relative;
      width: 100%;
      padding-top: 56.25%; /* 16:9 Aspect Ratio */
      background-color: #000;
      border-radius: 10px;
      overflow: hidden;
      box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
      margin-bottom: 30px;
    }

    #video-player {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      outline: none;
    }

    .controls {
      display: flex;
      justify-content: space-between;
      margin-bottom: 25px;
      gap: 15px;
      flex-wrap: wrap;
    }

    .url-input {
      flex-grow: 1;
      padding: 14px 20px;
      border: none;
      border-radius: 50px;
      font-size: 1.1rem;
      background: rgba(255, 255, 255, 0.1);
      color: white;
      outline: none;
      transition: background 0.3s;
    }

    .url-input:focus {
      background: rgba(255, 255, 255, 0.15);
    }

    .btn {
      padding: 14px 30px;
      border: none;
      border-radius: 50px;
      background: linear-gradient(to right, #ff8a00, #da1b60);
      color: white;
      font-size: 1.1rem;
      font-weight: 500;
      cursor: pointer;
      transition: transform 0.2s, box-shadow 0.2s;
      box-shadow: 0 4px 15px rgba(218, 27, 96, 0.4);
    }

    .btn:hover {
      transform: translateY(-2px);
      box-shadow: 0 6px 20px rgba(218, 27, 96, 0.6);
    }

    .btn:active {
      transform: translateY(1px);
    }

    .info-section {
      display: flex;
      flex-wrap: wrap;
      gap: 30px;
      margin-top: 20px;
    }

    .info-card {
      flex: 1;
      min-width: 300px;
      background: rgba(0, 0, 0, 0.4);
      border-radius: 10px;
      padding: 25px;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    .info-card h2 {
      font-size: 1.5rem;
      margin-bottom: 15px;
      color: #ff8a00;
    }

    .info-card p {
      line-height: 1.7;
      margin-bottom: 15px;
    }

    .status {
      font-weight: bold;
      color: #4caf50;
    }

    .features {
      padding: 0;
      margin-left: 20px;
    }

    .features li {
      margin-bottom: 10px;
      display: flex;
      align-items: center;
    }

    .features li:before {
      content: "✓";
      color: #4caf50;
      font-weight: bold;
      margin-right: 10px;
    }

    .server-details {
      margin-top: 30px;
      text-align: center;
      font-size: 1.1rem;
      opacity: 0.9;
    }

    .code {
      font-family: monospace;
      background: rgba(0, 0, 0, 0.4);
      padding: 3px 8px;
      border-radius: 4px;
    }

    footer {
      text-align: center;
      margin-top: 40px;
      padding-top: 20px;
      border-top: 1px solid rgba(255, 255, 255, 0.1);
      width: 100%;
      opacity: 0.8;
    }

    @media (max-width: 768px) {
      .container {
        padding: 15px;
      }

      h1 {
        font-size: 2.2rem;
      }

      .controls {
        flex-direction: column;
      }

      .btn {
        width: 100%;
      }
    }
  </style>
</head>
<body>
<div class="container">
  <header>
    <h1>HLS 视频流播放器</h1>
    <p class="subtitle">基于您的自定义HLS服务器实现自适应流媒体播放</p>
  </header>

  <div class="player-container">
    <video id="video-player" controls></video>
  </div>

  <div class="controls">
    <input
            type="text"
            class="url-input"
            id="stream-url"
            value="http://127.0.0.1:8080/index.m3u8"
            placeholder="输入HLS流URL..."
    >
    <button class="btn" id="play-btn">播放视频流</button>
  </div>

  <div class="info-section">
    <div class="info-card">
      <h2>关于此播放器</h2>
      <p>此播放器使用 <span class="status">hls.js</span> 库实现，可以在所有现代浏览器中播放HLS流媒体内容。</p>
      <p>HLS（HTTP Live Streaming）是苹果公司开发的基于HTTP的自适应比特率流媒体通信协议。</p>
      <p>播放器状态: <span id="player-status" class="status">等待播放指令</span></p>
    </div>

    <div class="info-card">
      <h2>技术特点</h2>
      <ul class="features">
        <li>支持自适应比特率切换</li>
        <li>低延迟播放</li>
        <li>支持多清晰度切换</li>
        <li>跨浏览器兼容</li>
        <li>响应式设计</li>
        <li>支持直播和点播</li>
      </ul>
    </div>
  </div>

  <div class="server-details">
    <p>您的HLS服务器运行在: <span class="code">http://127.0.0.1:8080/index.m3u8</span></p>
    <p>使用 <span class="code">ffplay http://127.0.0.1:8080/index.m3u8</span> 测试播放</p>
  </div>
</div>

<footer>
  <p>HLS 视频流播放器 | 与您的HLS服务器兼容</p>
</footer>

<script>
  document.addEventListener('DOMContentLoaded', function() {
    const video = document.getElementById('video-player');
    const playBtn = document.getElementById('play-btn');
    const urlInput = document.getElementById('stream-url');
    const statusText = document.getElementById('player-status');

    let hls = null;

    function initPlayer(url) {
      if (hls) {
        hls.destroy();
      }

      if (video.canPlayType('application/vnd.apple.mpegurl')) {
        // 原生支持HLS的浏览器（如Safari）
        video.src = url;
        statusText.textContent = "使用原生HLS播放";
      } else if (Hls.isSupported()) {
        // 使用hls.js支持其他浏览器
        hls = new Hls();
        hls.loadSource(url);
        hls.attachMedia(video);
        statusText.textContent = "使用hls.js播放";

        hls.on(Hls.Events.MANIFEST_PARSED, function() {
          statusText.textContent = "已加载媒体清单，准备播放";
          video.play();
        });

        hls.on(Hls.Events.ERROR, function(event, data) {
          console.error('HLS Error:', data);
          if (data.fatal) {
            switch(data.type) {
              case Hls.ErrorTypes.NETWORK_ERROR:
                statusText.textContent = "网络错误，尝试重新加载";
                hls.startLoad();
                break;
              case Hls.ErrorTypes.MEDIA_ERROR:
                statusText.textContent = "媒体错误，尝试恢复";
                hls.recoverMediaError();
                break;
              default:
                initPlayer(url);
                break;
            }
          }
        });
      } else {
        statusText.textContent = "错误：您的浏览器不支持HLS播放";
      }
    }

    playBtn.addEventListener('click', function() {
      const streamUrl = urlInput.value.trim();
      if (streamUrl) {
        statusText.textContent = "正在加载视频流...";
        initPlayer(streamUrl);
      } else {
        alert('请输入有效的HLS流URL');
      }
    });

    // 初始加载默认流
    initPlayer(urlInput.value);
  });
</script>
</body>
</html>